<?php

/**
 * +----------------------------------------------------------------------
 * | 润憬商城系统 [ 高性价比的通用商城系统 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2022~2023 https: *www.honc.fun All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
 * +----------------------------------------------------------------------
 * | Author: 润憬科技 Hon(陈烁临) <2275604210@qq.com>
 * +----------------------------------------------------------------------
 */

use cores\exception\BaseException;
use support\Log;
use support\Response;

/**
 * 获取当前应用id
 * @return string
 */
function app_name()
{
  $app = '';
  try {
    $app = request()->app;
  } catch (Exception) {
    $app = 'admin';
  }

  return $app;
}


/**
 * 结束执行
 */
function app_end()
{
  // if (\request()->isCli()) {
  //   exit(PHP_EOL);
  // }
  // throw new HttpResponseException(Response::create());
}

/**
 * 当前是否为调试模式
 * @return bool
 */
function is_debug(): bool
{
  return config('app.debug');
}

/**
 * 文本左斜杠转换为右斜杠
 * @param string $string
 * @return string
 */
function convert_left_slash(string $string): string
{
  return str_replace('\\', '/', $string);
}

/**
 * 隐藏手机号中间四位 13012345678 -> 130****5678
 * @param string $mobile 手机号
 * @return string
 */
function hide_mobile(string $mobile): string
{
  return substr_replace($mobile, '****', 3, 4);
}

/**
 * 获取当前登录的商城ID
 * @return int $storeId
 */
function getStoreId(): int
{
  return 10001;
}


/**
 * 左侧填充0
 * @param string $value
 * @param int $padLength
 * @return string
 */
function pad_left(string $value, int $padLength = 2): string
{
  return str_pad($value, $padLength, '0', STR_PAD_LEFT);
}

/**
 * 重写trim方法 (解决int类型过滤后后变为string类型)
 * @param $str
 * @return string|void
 */
function my_trim($str)
{
  return is_string($str) ? trim($str) : $str;
}

/**
 * 重写htmlspecialchars方法 (解决int类型过滤后后变为string类型)
 * @param $string
 * @return string|void
 */
function my_htmlspecialchars($string)
{
  return is_string($string) ? htmlspecialchars($string, ENT_COMPAT) : $string;
}

/**
 * 过滤emoji表情
 * @param $text
 * @return null|string|string[]
 */
function filter_emoji($text)
{
  if (!is_string($text)) {
    return $text;
  }
  // 此处的preg_replace用于过滤emoji表情
  // 如需支持emoji表情, 需将mysql的编码改为utf8mb4
  return preg_replace('/[\xf0-\xf7].{3}/', '', $text);
}

/**
 * 根据指定长度截取字符串
 * @param $str
 * @param int $length
 * @return bool|string
 */
function str_substr($str, int $length = 30)
{
  if (strlen($str) > $length) {
    $str = mb_substr($str, 0, $length);
  }
  return $str;
}



/**
 * 输出错误信息
 * @param string $message 报错信息
 * @param int|null $status 状态码,默认为配置文件status.error
 * @param array $data 附加数据
 * @throws BaseException
 */
function throwError(string $message, ?int $status = null, array $data = [])
{
  is_null($status) && $status = config('status.error');
  throw new BaseException(['status' => $status, 'message' => $message, 'data' => $data]);
}

/**
 * 下划线转驼峰
 * @param string $uncamelized_words
 * @param string $separator
 * @return string
 */
function camelize(string $uncamelized_words, string $separator = '_'): string
{
  $uncamelized_words = $separator . str_replace($separator, " ", strtolower($uncamelized_words));
  return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator);
}

/**
 * 驼峰转下划线
 * @param string $camelCaps
 * @param string $separator
 * @return string
 */
function uncamelize(string $camelCaps, string $separator = '_'): string
{
  return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}

/**
 * 生成密码hash值
 * @param string $password
 * @return string
 */
function encryption_hash(string $password): string
{
  return password_hash($password, PASSWORD_DEFAULT);
}


/**
 * 多维数组合并
 * @param $array1
 * @param $array2
 * @return array
 */
function array_merge_multiple($array1, $array2): array
{
  $merge = $array1 + $array2;
  $data = [];
  foreach ($merge as $key => $val) {
    if (
      isset($array1[$key])
      && is_array($array1[$key])
      && isset($array2[$key])
      && is_array($array2[$key])
    ) {
      $data[$key] = is_assoc($array1[$key]) ? array_merge_multiple($array1[$key], $array2[$key]) : $array2[$key];
    } else {
      $data[$key] = $array2[$key] ?? $array1[$key];
    }
  }
  return $data;
}

/**
 * 判断是否为自定义索引数组
 * @param array $array
 * @return bool
 */
function is_assoc(array $array): bool
{
  if (empty($array)) return false;
  return array_keys($array) !== range(0, count($array) - 1);
}

/**
 * 二维数组排序
 * @param $arr
 * @param $keys
 * @param bool $desc
 * @return array
 */
function array_sort($arr, $keys, bool $desc): array
{
  $key_value = $new_array = array();
  foreach ($arr as $k => $v) {
    $key_value[$k] = $v[$keys];
  }
  if ($desc) {
    arsort($key_value);
  } else {
    asort($key_value);
  }
  reset($key_value);
  foreach ($key_value as $k => $v) {
    $new_array[$k] = $arr[$k];
  }
  return $new_array;
}

/**
 * 隐藏敏感字符
 * @param $value
 * @return string
 */
function substr_cut($value): string
{
  $strlen = mb_strlen($value, 'utf-8');
  if ($strlen <= 1) return $value;
  $firstStr = mb_substr($value, 0, 1, 'utf-8');
  $lastStr = mb_substr($value, -1, 1, 'utf-8');
  return $strlen == 2 ? $firstStr . str_repeat('*', $strlen - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr;
}

/**
 * 获取当前系统版本号
 * @return string
 * @throws BaseException
 */
function get_version(): string
{
  return \cores\library\Version::getVersion();
}

/**
 * 获取全局唯一标识符
 * @param bool $trim
 * @return string
 */
function get_guid_v4(bool $trim = true): string
{
  // Windows
  if (function_exists('com_create_guid') === true) {
    $charid = com_create_guid();
    return $trim ? trim($charid, '{}') : $charid;
  }
  // OSX/Linux
  if (function_exists('openssl_random_pseudo_bytes') === true) {
    $data = openssl_random_pseudo_bytes(16);
    $data[6] = chr(ord($data[6]) & 0x0f | 0x40);    // set version to 0100
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80);    // set bits 6-7 to 10
    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
  }
  // Fallback (PHP 4.2+)
  mt_srand(intval((float)microtime() * 10000));
  $charid = strtolower(md5(uniqid((string)rand(), true)));
  $hyphen = chr(45);                  // "-"
  $lbrace = $trim ? "" : chr(123);    // "{"
  $rbrace = $trim ? "" : chr(125);    // "}"
  return $lbrace .
    substr($charid, 0, 8) . $hyphen .
    substr($charid, 8, 4) . $hyphen .
    substr($charid, 12, 4) . $hyphen .
    substr($charid, 16, 4) . $hyphen .
    substr($charid, 20, 12) .
    $rbrace;
}



function web_path(string $path = ''): string
{
  return public_path($path);
}

/**
 * Data path
 * @param string $path
 * @return string
 */
function data_path(string $path = ''): string
{
  static $dataPath = '';
  if (!$dataPath) {
    $dataPath = \config('app.data_path') ?: run_path('data');
  }
  return path_combine($dataPath, $path);
}

function root_path()
{
  return base_path();
}

/**
 * 获取当前域名及根路径
 * @return string
 */
function base_url(): string
{
  static $baseUrl = '';
  if (empty($baseUrl)) {
    $request = request();
    // url协议，设置强制https或自动获取
    $scheme = $request->header('x-forwarded-proto', '');
    $scheme = $scheme ? $scheme . ':' : 'http:';
    // url子目录
    $rootUrl = root_url();
    // 拼接完整url
    $baseUrl = "{$scheme}//" . $request->host() . $rootUrl;
  }
  return $baseUrl;
}

/**
 * 获取当前url的子目录路径
 * @return string
 */
function root_url(): string
{
  static $rootUrl = '';
  if (empty($rootUrl)) {
    // $url = request()->host(true);
    $rootUrl =  '/';
  }
  return $rootUrl;
}

/**
 * 获取当前uploads目录访问地址
 * @return string
 */
function uploads_url(): string
{
  return base_url() . 'uploads/';
}

/**
 * 获取当前temp目录访问地址
 * @return string
 */
function temp_url(): string
{
  return base_url() . 'temp/';
}


/**
 * 写入日志 (使用tp自带驱动记录到runtime目录中)
 * @param mixed $value
 * @param string $type
 */
function log_record($value, string $type = 'info')
{
  $content = is_string($value) ? $value : print_r($value, true);
  Log::log($type, $content);
}



/**
 * 时间戳转换日期
 * @param int|string $timeStamp 时间戳
 * @param bool $withTime 是否关联时间
 * @return false|string
 */
function format_time($timeStamp, bool $withTime = true)
{
  $format = 'Y-m-d';
  $withTime && $format .= ' H:i:s';
  return $timeStamp ? date($format, $timeStamp) : '';
}
